package com.example.demo.service.impl;

import com.example.demo.constant.MessageConstant;
import com.example.demo.context.BaseContext;
import com.example.demo.exception.AddressBookBusinessException;
import com.example.demo.exception.ShoppingCartBusinessException;
import com.example.demo.mapper.AddressBookMapper;
import com.example.demo.mapper.OrderDetailMapper;
import com.example.demo.mapper.OrderMapper;
import com.example.demo.mapper.ShoppingCartMapper;
import com.example.demo.pojo.PageResult;
import com.example.demo.pojo.dto.OrderPageDTO;
import com.example.demo.pojo.dto.OrderPayDTO;
import com.example.demo.pojo.dto.OrderSubmitDTO;
import com.example.demo.pojo.entity.AddressBook;
import com.example.demo.pojo.entity.Order;
import com.example.demo.pojo.entity.OrderDetail;
import com.example.demo.pojo.entity.ShoppingCart;
import com.example.demo.pojo.vo.OrderSubmitVO;
import com.example.demo.pojo.vo.OrderVO;
import com.example.demo.service.OrderService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Override
//    @Transactional
    public OrderSubmitVO submit(OrderSubmitDTO orderSubmitDTO) {
        Long userId= BaseContext.getCurrentId();
        List<ShoppingCart> shoppingCartList=shoppingCartMapper.getAllSelected(userId);
        if(shoppingCartList==null||shoppingCartList.size()==0){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //向订单表中插入一条数据
        Order order = new Order();
        BeanUtils.copyProperties(orderSubmitDTO,order);
        order.setOrderTime(LocalDateTime.now());
        order.setPayStatus(Order.UN_PAID);
        order.setStatus(Order.PENDING_PAYMENT);
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setPhone(null);
        order.setConsignee(null);
        order.setUserId(userId);
        order.setAddress(null);

        orderMapper.insert(order);


        //向订单明细表中插入n条数据
        List<OrderDetail> orderDetailList=new ArrayList<>();
        for(ShoppingCart cart:shoppingCartList){
            OrderDetail orderDetail=new OrderDetail();
            BeanUtils.copyProperties(cart,orderDetail);
            orderDetail.setOrderId(order.getId());//设置当前订单明细关联的订单
            orderDetail.setCreateTime(LocalDateTime.now());
            orderDetailList.add(orderDetail);
        }
        orderDetailMapper.insertBatch(orderDetailList);

        //清空当前用户的购物车
        shoppingCartMapper.deleteSelectedByUserId(userId);
        //封装VO返回数据
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .list(orderDetailList)
                .orderTime(order.getOrderTime())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .build();

        return orderSubmitVO;
    }

    @Override
    public void payment(OrderPayDTO orderPayDTO) {

        AddressBook addressBook=addressBookMapper.getById(orderPayDTO.getAddressBookId());
        if(addressBook==null){
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long userId=BaseContext.getCurrentId();

        Order orderDB=orderMapper.getByNumberAndUserId(orderPayDTO.getOrderNumber(),userId);

        Order order=Order.builder()
                .id(orderDB.getId())
                .addressBookId(orderPayDTO.getAddressBookId())
                .status(Order.WAIT_DELIVERY)
                .payStatus(Order.PAID)
                .freight(orderPayDTO.getFreight())
                .remark(orderPayDTO.getRemark())
                .phone(addressBook.getPhone())
                .address(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName()+addressBook.getDetail())
                .consignee(addressBook.getConsignee())
                .payMethod(orderPayDTO.getPayMethod())
                .checkoutTime(LocalDateTime.now())
                .build();

        orderMapper.update(order);
    }

    @Override
    public List<Order> list(Integer status) {
        Order order=new Order();
        order.setStatus(status);
        order.setUserId(BaseContext.getCurrentId());
        return orderMapper.list(order);
    }

    @Override
    public OrderVO getOrderInfo(Long id) {
        OrderVO orderVO = new OrderVO();
        Order order=orderMapper.getById(id);
        BeanUtils.copyProperties(order,orderVO);
        Long orderId=order.getId();
        List<OrderDetail> orderDetailList=orderDetailMapper.getByOrderId(orderId);
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }

    @Override
    public void cancel(Long id,String cancelReason) {
        Order orderDB=orderMapper.getById(id);

        Order order=Order.builder()
                .cancelTime(LocalDateTime.now())
                .cancelReason(cancelReason)
                .status(Order.CANCELLED)
                .payMethod(Order.REFUND)
                .build();

        orderMapper.update(order);
    }

    @Override
    public void unPayment(OrderPayDTO orderPayDTO) {
        AddressBook addressBook=addressBookMapper.getById(orderPayDTO.getAddressBookId());

        Long userId=BaseContext.getCurrentId();

        Order orderDB=orderMapper.getByNumberAndUserId(orderPayDTO.getOrderNumber(),userId);

        Order order=Order.builder()
                .id(orderDB.getId())
                .consignee(addressBook.getConsignee())
                .freight(orderPayDTO.getFreight())
                .status(Order.PENDING_PAYMENT)
                .payStatus(Order.UN_PAID)
                .payMethod(orderPayDTO.getPayMethod())
                .remark(orderPayDTO.getRemark())
                .number(orderPayDTO.getOrderNumber())
                .address(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName()+addressBook.getDetail())
                .build();

        orderMapper.update(order);
    }

    @Override
    public void confirm(Long id) {
        Order order=orderMapper.getById(id);
        order.setStatus(Order.DELIVERY_IN_PROGRESS);
        orderMapper.update(order);
    }

    @Override
    public void finish(Long id) {
        Order order=orderMapper.getById(id);
        order.setStatus(Order.COMPLETED);
        orderMapper.update(order);
    }

    @Override
    public PageResult page(OrderPageDTO orderPageDTO) {
        PageHelper.startPage(orderPageDTO.getPage(), orderPageDTO.getPageSize());
        Page<Order> page=orderMapper.pageQuery(orderPageDTO);
        return new PageResult(page.getTotal(),page.getResult());
    }
}
